package com.cskaoyan.config;
//ctrl + alt + o 删掉为导入的的包
import com.cskaoyan.realm.AdminRealm;
import com.cskaoyan.realm.WxRealm;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.ArrayList;
import java.util.LinkedHashMap;

/**
 * @author: lds
 * @clsss: ShiroConfig
 */
@Configuration
public class ShiroConfig {
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //认证失败后重定向的url
//        shiroFilterFactoryBean.setLoginUrl("/auth/login");
        //key对应请求url value对应过滤器
        LinkedHashMap<String, String> filterMap = new LinkedHashMap<>();
        //login(username,password)success
        //失败重新登陆

        filterMap.put("/admin/auth/login","anon");
        filterMap.put("/wx/auth/login","anon");
        filterMap.put("/admin/auth/info","anon");
        filterMap.put("/wx/home/index","anon");
        filterMap.put("/wx/storage/fetch","anon");
        filterMap.put("/admin/auth/loginByEmail","anon");
        filterMap.put("/admin/auth/sendEmail","anon");
        filterMap.put("/logout/kickout","anon");
        filterMap.put("/wx/**","anon");
        filterMap.put("/wx/storage/**","anon");
        filterMap.put("/**","authc");
        //authc
        //当你分配了perml的权限时才能访问need/perm这个请求
//        filterMap.put("/need/perm","perms[perm1]");
        //优选方式是声明式
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
        return shiroFilterFactoryBean;
    }
    @Bean/*也可以用@Component注册*/  /*把此组件注册给securityManager*/
    public CustomAuthenticator authenticator(AdminRealm adminRealm, WxRealm wxRealm) {
        CustomAuthenticator customAuthenticator = new CustomAuthenticator();
        ArrayList<Realm> realmList = new ArrayList<>();
        realmList.add(adminRealm);
        realmList.add(wxRealm);
        customAuthenticator.setRealms(realmList);
        return customAuthenticator;
    }
    //shiro核心组件SecurityManager
    @Bean
    public DefaultWebSecurityManager securityManager(AdminRealm adminRealm , DefaultWebSessionManager webSessionManager,
                                                     CustomAuthenticator customAuthenticator) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(adminRealm);
        securityManager.setSessionManager(webSessionManager);
        securityManager.setAuthenticator(customAuthenticator);
        return securityManager;

    }
    /**
     * 声明式权限鉴定，注解形式所需组件
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager){
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }
    //处理异常的方式
    /*使用映射处理异常： key为异常全类名 value 为异常处理的请求*/
//    @Bean
//    public SimpleMappingExceptionResolver simpleMappingExceptionResolver() {
//        SimpleMappingExceptionResolver simpleMappingExceptionResolver = new SimpleMappingExceptionResolver();
//        Properties mappings = new Properties();
//        mappings.put("org.apache.shiro.authz.AuthorizationException","/auth/login");
//        simpleMappingExceptionResolver.setExceptionMappings(mappings);
//        return simpleMappingExceptionResolver;
//    }
    @Bean
    public DefaultWebSessionManager webSessionManager() {
        CustomSessionManager customSessionManager = new CustomSessionManager();
        customSessionManager.setGlobalSessionTimeout(System.currentTimeMillis()+1000*60*60*24);
        return customSessionManager;
    }
}
